package com.wn.gateway.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wn.common.ResponseEntity;
import com.wn.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

/**
 * @ author     ：NST
 * @ date       ：Created in 2022/10/25 14:32
 * @ description：登录认证过滤器
 * @ modified By：
 * @ version:
 */
@Component
public class LoginFIlter implements GlobalFilter, Ordered {
    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    private JwtUtils jwtUtils = new JwtUtils();
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        //登录请求或静态资源放行
        if (path.contains("login")||path.endsWith(".png")) {
            //添加特定头信息 通过下一级的权限过滤
            request.mutate().header("release", "release").build();
            return chain.filter(exchange);
        }
        String token = request.getHeaders().getFirst("token");
        if (token != null && jwtUtils.verifySecretJWT(token)) {
            //token有效 进行判断redis中是否过期
            String tokenKey = "token" + jwtUtils.getInfo(token, "id");
            String userKey = "user" + jwtUtils.getInfo(token, "id");
            //如果过期 返回令牌过期
            if (redisTemplate.opsForValue().get(tokenKey) == null) {
                return exchange.getResponse().writeWith(Mono.just(result(exchange, "702", "登录过期,请重新登录")));
            }
            //token未过期,进行token续期 同步续期用户信息缓存
            redisTemplate.expire(tokenKey, 30, TimeUnit.MINUTES);
            redisTemplate.expire(userKey, 30, TimeUnit.MINUTES);
            return chain.filter(exchange);
        }
        return exchange.getResponse().writeWith(Mono.just(result(exchange, "701", "先登录")));
    }

    public DataBuffer result(ServerWebExchange exchange, String code, String msg) {
        ServerHttpResponse response = exchange.getResponse();
        ResponseEntity<String> responseEntity = new ResponseEntity<>(code, msg, null);
        byte[] bytes = null;
        try {
            bytes = new ObjectMapper().writeValueAsString(responseEntity).getBytes(StandardCharsets.UTF_8);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        DataBuffer dataBuffer = response.bufferFactory().wrap(bytes);
        response.getHeaders().add("Content-type", "application/json;charset=utf-8");
        return dataBuffer;
    }


    @Override
    public int getOrder() {
        return 0;
    }
}
